跨页面通信

Z 实际

一 acuviewer.php aculive.php

  1. localStorage:video播放速度,质量,字幕
  2. iframe操作:全屏同源
  3. postmessage:全屏跨域;其他大多通信,包括全屏聊天室通知
  4. location.hash:聊天室全屏,为iframe中body添加样式
  5. cookie:登陆状态,没有接触
  6. server:直播状态及其他,没有接触

2018.2.8 星期四 12:24

A [跨页面通信的各种姿势]

链接:https://juejin.im/post/59bb7080518825396f4f5177
作者简介:nekron 蚂蚁金服·数据体验技术团队 2017.9.15
$_YX: [跨页面通信的各种姿势]

将跨页面通讯类比计算机进程间的通讯,其实方法无外乎那么几种,而web领域可以实现的技术方案主要是类似于以下两种原理:

  • 获取句柄,定向通讯
  • 共享内存,结合轮询或者事件通知来完成业务逻辑

由于第二种原理更利于解耦业务逻辑,具体的实现方案比较多样。以下是具体的实现方案,简单介绍下,权当科普:

一 获取句柄

1.1 具体方案

父页面通过window.open(url, name)方式打开的子页面可以获取句柄,然后通过postMessage完成通讯需求。

1.2 tips

1.3 优劣

缺点是只能与自己打开的页面完成通讯,应用面相对较窄;但优点是在跨域场景中依然可以使用该方案。

二 localStorage

2.1 具体方案

2.2 tips

2.3 优劣

API简单直观,兼容性好,除了跨域场景下需要配合其他方案,无其他缺点

三 BroadcastChannel

3.1 具体方案

和localStorage方案基本一致,额外需要初始化

3.2 优劣

和localStorage方案没特别区别,都是同域、API简单,BroadcastChannel方案兼容性差些(chrome > 58),但比localStorage方案生命周期短(不会持久化),相对干净些。

四 SharedWorker

4.1 具体方案

4.2 优劣

5.1 具体方案

一个古老的方案,有点localStorage的降级兼容版,我也是整理本文的时候才发现的,思路就是往document.cookie写入值,由于cookie的改变没有事件通知,所以只能采取轮询脏检查来实现业务逻辑。
方案比较丑陋,势必被淘汰的方案,贴一下原版思路地址,我就不写demo了。
communication between browser windows (and tabs too) using cookies

5.2 优劣

相较于其他方案没有存在优势的地方,只能同域使用,而且污染cookie以后还额外增加AJAX的请求头内容。

六 Server

之前的方案都是前端自行实现,势必受到浏览器限制,比如无法做到跨浏览器的消息通讯,比如大部分方案都无法实现跨域通讯(需要增加额外的postMessage逻辑才能实现)。通过借助服务端,还有很多增强方案,也一并说下。

6.1 乞丐版

6.2 Server-sent Events / Websocket

6.3 消息队列

其它:
$_YX: [015 跨页面通信的各种姿势 - 掘金]

================

B 使用Cookie做跨页面通信

https://www.web-tinker.com/article/20122.html

Cookie的存储在硬盘中的,而网页是运行在内存中的,他们会共用硬盘上的Cookie。而document.cookie这个属性不仅仅是一个Setter属性,还是个Getter属性。当我们访问这个属性时,它会从硬盘上保存的Cookie中读入数据。而Cookie是以域名和目录名来储存的,它没有精确到页面。这就意味着多个页面是共用一个Cookie的。既然页面之间有共同的数据存储区域,我们就可以利用它来实现跨页面的通信。

但是Cookie并没有change之类的事件,我们只能使用一个计时器去扫描。计时器的时间间隔可以依据项目需求来设置。下面是例子

<script>
    onload=function(){
        //创建一个文本节点,用来显示当前数据
        var t=document.createTextNode("");
        document.body.appendChild(t);
        //创建计时器来扫描Cookie,间隔是1秒
        setInterval(function(){
            //读取Cookie
            var v=document.cookie.match(/data=(.+?)(?=;|$)/);
            t.data=v?decodeURIComponent(v[1]):"";
        },1000);
        //按钮点击时把文本框内的内容放入Cookie中
        btn.onclick=function(){
            document.cookie="data="+encodeURIComponent(inp.value);
        };
    };  
</script>
<input id="inp" /><br/>
<input id="btn" type="button" value="设置" />

$_PS: 上面那些都不是重点;

  1. A 内容丰富,但是华而不实;
  2. 只有postmessage,localstorage
  3. 勉强Server
  4. cookie已经是没落方案了

=================

C [跨浏览器tab页的通信解决方案尝试]

https://segmentfault.com/a/1190000011207317
RoyalRover 2017年09月17日发布

$_YX: [015【第1060期】跨浏览器tab页的通信解决方案尝试]

一 目标

二 畅想

2.1 case 1

两个需要交互的tab页面具有依赖关系。

如 A页面中通过JavaScript的window.open打开B页面,或者B页面通过iframe嵌入至A页面,此种情形最简单,可以通过HTML5的 window.postMessage API完成通信,由于postMessage函数是绑定在 window 全局对象下,因此通信的页面中必须有一个页面(如A页面)可以获取另一个页面(如B页面)的window对象,这样才可以完成单向通信;B页面无需获取A页面的window对象,如果需要B页面对A页面的通信,只需要在B页面侦听message事件,获取事件中传递的source对象,该对象即为A页面window对象的引用:

2.2 case 2

两个打开的页面属于同源范畴。
若要实现两个互不相关的通源tab页面通信,可以使用一种比较巧妙的方式:localstorage。localStorage的存储遵循同源策略,因此

幸好,HTML5提供了storage事件,通过window对象侦听storage事件,

2.3 case 3

两个互不相关的tab页面通信。
这种情况才是最急需解决的问题,如何实现两个没有任何关系的tab页面通信,这需要一些技巧,而且需要有同时修改这两个tab页面的权限,否则根本不可能实现这两个tab页的能力。

在上述条件满足的情况下,我们就可以使用case1 和 case2的技术完成case 3的需求,这需要我们巧妙的结合HTML5 postMessage API 和 storage事件实现这两个毫无关系的tab页面的连通。为此,我想到了iframe,通过在这两个tab页嵌入同一个iframe页实现“桥接”,最终完成通信:

tab A —–> iframe A[bridge.html]
|
|
|/
iframe B[bridge.html] —–> tab B

..

D [前端通信篇]

背景

什么是同源策略及限制?前后端通信的ajax用原生该如何写?跨域问题该如何解决?如果你有这个疑问,这篇文章很适合你。

什么是同源策略及限制

同源的“源”包含3层意思:协议、域名和端口。三者之中只要有一个不一样,那就是可以称源不一样。

同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是浏览器发出的用于隔离潜在恶意文件的关键的安全机制。

那么这个限制有哪些呢?主要有3个方面:

  1. Cookie、LocalStorage和IndexDB无法读取;
  2. DOM无法获得;
  3. AJAX请求不能发送;

前后端的通信方式

Ajax
Websocket
CORS
Ajax是同源下的通信方式;Websocket不受同源策略的限制;CORS是新的通信标准,它支持跨域通信也支持同源通信。

如何创建一个Ajax

跨域通信的几种方式

1. JSONP
jsonp解决跨域本质是通过script标签的异步加载实现的,使用script标签进行ajax传输,不受同源策略的影响。

2. Hash
Hash就是url后面的#,hash改变页面是不会刷新的,所以这也是hash可以做跨域的原因。Search是url后面?后面的内容。所以search是不能做跨域通信的。

3. postMessage
h5中新增的方法

4. websocket
websocket可以做跨域,但是它出现的目的是为了解决实时通信的。

5. 搭建web服务器,对跨域请求做一个node代理
现在前端很多公司都会进行单独的部署,最多的就是使用express快速构建一个web服务器,用中间件的方式写一个代理。

knowledge is no pay,reward is kindness
0%